\documentclass[11pt]{article}
\author{Ivan Bogouchev \and Ognyan Pertchev \and Gueorgui Tzotchev}
\usepackage[latin1]{inputenc}
\usepackage[francais]{babel}
\usepackage{graphicx}
\usepackage{verbatim}
\title{FOGE2 le retour}
\frenchspacing
\begin{document}
\maketitle

\pagebreak
\tableofcontents
\pagebreak

\section{Présentation du TER}

\subsection{Introduction (Foge d'origine)}

FOGE est une librairie Perl, dédiée à la gestion de questionnaires,
destinés pour le WEB. La version d'origine était écrite par Christian
Queinnec pour faciliter le deploiment de questionnaires d'evaluation
des enseignements. Par la suite, deux étudiants - Rémi Bantos et David
Haguenauer ont fait une réécriture orientée objet visant à rendre la
librairie modulaire, facilitant l'ajout de nouvelles fonctionalitées.

FOGE propose aux créateurs de questionnaires les objets et
fonctionnalités suivantes:

\begin{enumerate}
\item objets représentant des questions: selon sa nature une question peut
etre représentée sous forme d'un menu, d'un groupe de cases à cocher
(ou boutons radio) ou d'un textfiled (ou textarea).

\item objets représentant des sections - une section dans le vocabulaire
FOGE est une collection de questions, utilisée pour regrouper des
questions concernant le même sujet.

\item objets représentant le formulaire - un formulaire dans le
vocabulaire FOGE est une collection de sections. Le formulaire est
l'objet principal d'un questionnaire, capable de servir la page HTML
du questionnaire, insérer les réponses dans une base de données,
analyser les réponses pour en extraire des statistiques.

\item objets représentant des statistiques associées au questions,
sections et formulaires, proposant plusieurs types de statistiques
(histogrames, camamberts, ...) choisies par le concepteur du
questionnaire.

\item gestion des droits d'effectuer certaines actions (visualiser le
questionnaire, répondre, voir des différent type de statistiques) en
fonction de la date courrante, l'adresse ip de l'utilisateur ...

\end{enumerate}

Du point de vue des utilisateurs, FOGE offre les fonctionnalités
suivantes: 

\begin{enumerate}
\item générer la page html visualisant le questionnaire en respectant la
norme HTML4 et utilisant les CSS. Les messages produits par FOGE (tels
que les noms des boutons, les messages d'erreur, la confirmation de
réception d'une réponse au questionnaire) peuvent etre traduits
automatiquement par FOGE. 

\item créer les tables SQL nécessaires pour le stokage des réponses.

\item insérer dans la base de données les réponses (soummises via la page,
déjà servie par FOGE) en veillant à ce que les réponses respectent les
contraintes définies dans le questionnaire:
  \begin{enumerate}
  \item droit de répondre (ip, utilisateur, date ....)
  \item réponses au questions (balisées) obligatoires
  \item réponses conformes (à une expression régulière par ex.)
  \end{enumerate}

\item extraire des diverses statistiques sur la répartition des
réponses. (dans FOGE2 les statistiques sont choisies par le concepteur
du questionnaire).

\end{enumerate}

\centerline{\includegraphics{formulaire}}
\subsection{But du TER}

On s'est proposé d'étendre les fonctionnalités proposées
par FOGE (surtout du point de vue utilisateur), pour permettre
d'effectuer des sondages exhaustives, ainsi que la
construction de toutes les statistques nécessaires à l'analyse
adequate des données.
(securité)

On a donc rajouter les fonctionnalités suivantes:

\begin{description}

\item[filtres] - un filtre permet de restreindre l'ensemble des soumissions
prises en compte par les différentes fonctionnalités offertes par
FOGE. La restriction se fait en ne gardant que les soumissions
conformes à certains critères. 

\item[vues] - une vue permet de restreindre l'ensemble des questions pris en
compte par les différente fonctionnalités offertes par
FOGE. L'utilisateur définit une vue, en choisissant les questions,
dont les réponses l'intéressent.

\item[fiche-par-fiche] - la consultations d'un vote, en regroupant les
réponses à toutes les questions qu'un utilisateur/étudiant à fait. La
consultation du vote fiche-par-fiche, exploite les sous-ensembles
définits, après le filtrage et la définition de la vue.

\item[securité] - concentrer la gestion des droits d'accès dans un module
dédié à cet effet. Définir formellement les différents types de
droits, actions et utilisateurs et les étapes de vie d'un
questionnaire.

\item[nouvelles statistiques] - les statistiques dédiées à la
recherche d'interdépendances entre les réponses des différentes
questions 

\item[nouveaux type de questions] - liées logiquement (débloquer une des
questions seulement si la réponse de telle autre questions est
conforme à certains critères.

\item[choisir les statistique au moment de la consultation] - permettre à
un utilisateur de choisir les statistiques qui lui conviennent, au moment
de la consultation.

\item[status] - vue détaillé de l'état du questionnaire

\item[adaptation] - adapter les parties exsitantes afin d'utiliser les nouvelles
fonctionnalités: filtrage, vues, sécurité

\end{description}



\section{Les nouvelle fonctionnalitées en détailles}

Pour décrir en détailles les extentions apportées, expliquons
brièvement comment un script FOGE accompli ses fonctions de base
(servir la page html du questionnaire, insérer les réponses dans la
base de donées et afficher les statistiques).

Un script FOGE est aussi un script CGI. En tant que tel, il est
lancé par le serveur web et reçoit dans son environnement plusieurs
informations (le query string des méthodes GET et POST de HTTP, l'ip
d'où le formulaire a été invoqé ...).

Aprés avoir construit toutes les questions et sections et le formulaire
les contentant, le script FOGE invoque la méthode main() du formulaire
(form->main()).

Ensuite en fonction des arguments passés par le query string, le
formulaire décide de l'action qui lui est demandée. En fonction de
l'action demandée une des méthodes serve(), handle\_submission() ou
print\_stats() sera appelée. C'est pour ça qu'on les appelle des
\_actions\_.

Quelle que soit l'action demandée, l'objet formulaire (de classe Form)
effectue une partie du travaille concernant le formulaire dans sa
totalité et délégue le reste du travaille à ses sections.  De même,
après avoir effectué une partie du travaille la concernant en
totalité, la section va déléguer le reste du travaille au questions
qu'elle contient.

Cette approche modulaire permet de structurer le code et
rend aisé l'ajout de nouvelles fonctionnalités.


\subsection{Filtres}

Le procédé de filtrage est un outil qui permet de rechercher
avec plus de précisions les informations qui nous intéressent et de
mettre en evidance des réslutats qui vont permettre par la suite
d'exploiter mieux les staistiques obtenues.
Les filtres diminuent l'ensemble de recherche, et montrent les
corrélations entre les différentes questions.
Le choix de filtres va affecter le manière dont les statistiques vont
être calculés. De ce choix dépend, en grande partie, la pérception
des résultats,

Un filtre est un objet qui se place entre la base de donées est les
parties de FOGE qui en extraient des informations (statistiques,
consultations fiche-par-fiche). Il permet d'extraire des statistiques
pour un sous-ensemble des réponses du questionnaire. Ce sous-ensemble
correspond à certains critères, choisis par l'utilisateur au moment de
la consultation des statistiques.

\subsubsection{Différents types de filtres}

Les différent types de filtres choisissent les sous-ensembles associés
selon des critères différents. Le choix du filtre va affecter la
manière dont les statistiques vont être calculés. De ce choix dépend,
en grande partie, la pérception des résultats.
Actuellement on a implémenté deux filtres:

Le premier filtre permet de choisir les soumissions, en fonction des
addresses ip d'origine. Par exemple on aimerit savoir quelle
partie des étudiants ont utilisé les salles du CCE pour répondre au
questionnaire et ensuite, voir quelle partie de ces étudiants a
affirmer vouloir travailler plus chez eux, qu'aux salles du CCE.

Le deuximème filtre, permet de choisir les soumissions, ayant donné
telle ou telle réponse à une ou à plusieurs ou à la totalité des
questions du questionnaire. Cela permet de voir la répartition des
réponses dans la sous-population qui satisfait aux critères de
filtrage. 

(on n'a toujours pas fixé un nom pour les deux types de filtres:

    ?FilterIP, IPFilter, NetFilter (pour le filtrage des addresses)?

    ?FilterTemplate (pour filtrer en fonction des réponses)?

)


\subsubsection{Constructions des filtres}

Le critère de filtrage, pour le FilterIP est une chaine décrivant une
addresse ip, où on peut utiliser le caractère '*' pour signifier un
groupe d'adresses ip. Par exemple pour les machines du CCE on
pourrait utiliser le filtre construit à l'aide de "134.157.116.*".

Pour construire le filtre template, FOGE sert à l'utilisateur qui veut
filtrer, la page HTML du questionnaire, telle qu'elle serait servie à
un étudiant pour remplir le questionnaire, mais avec quelques légères
modifications: 
\begin{itemize}
  \item le questions à choix unique sont devenus des questions à
choix multiples. Donc l'utilisateurs remplira
  \item la réponse à toutes les questions est facultative
\end{itemize}

\centerline{\includegraphics{filtre}}

Donc l'utilisateur répondra au parties du questionnaire qui
l'intéressent, pour construiure un filtre qui va séléctionner de la
base de données seulement les soumissions, qui corréspondent à la
façon dont l'utilisateur à rempli le questionnaire de construction du
filtre. 


\subsubsection{Implémentation}

Pour chaque soumission FOGE stocke dans une table SQL ("foge\_answer") un
identificateur de la soumission, l'adresse ip et le nom du
questionnaire. Pour chaque section du questionnaire, il existe une
table SQL, qui contient les réponses aux questions de la section. Le
premier àtribut de cette relation est un identificateur référencant
l'identificateur de la table "foge\_answer". Ainsi pour avoir les
réponses qu'un étudiant a faites (et ensuite calculer les statistiques
dessus), on fait la jointure entre la table foge\_answer, et les tables
des sections su l'attribut id.
Donc pour filtrer, il nous suffit de garder dans la table foge\_answer
(actuellment on crée un table temporaire, qui masque foge\_answer) les
soumissions qui correspondent aux critères de filtrage.

Par exemple pour avoir toutes les soumissions, qui ont répondu 'oui' à
la question 'Question1' de la section 'Section1', on définit la table
suivante:

\begin{verbatim}
CREATE TEMP TABLE foge\_answer
SELECT f.*
FROM foge\_answer f, Section1 s
WHERE f.enquiry="Poll" and f.id = s.id and s.Q1 = "oui";
\end{verbatim}

Donc le critère de filtrage est traduit en une expression WHERE du
langage SQL.


\subsection{Vues}

Une vue donne acces à un sous-ensemble des questions. Elle
permet de présenter à l'utilisateur (et au programmeur) différentes
perspectives du même questionnaire. Son utilité se manifeste, surtout
lors du dépouillement des statistiques à des questionnaire longs, en
permettant de choisir de voir des statistiques sur une (petite) partie
des questions.

Aprés avoir définit la vue qui l'intéresse, l'utilisateur peut
visualiser les statistiques, consulter les réponses aux questionnaire
fiche par fiche, ou décider de définir un filtre. En tout les cas les
fonctionnalités offertes par FOGE, utiliseront l'ensemble des questions
définies dans la vue et non celles définies dans le formulaire.


\subsubsection{Construction des vues}

Actuellement on a implémenté deux façons de construire une vue. 

La première consiste à afficher la liste des questions du
formulaire, groupées par section et de donner à l'utilisateur la
possibilité de choisir celles qui l'intéressent (à l'aide de cases à
cocher, affichées à coté des titres des questions).
Initialement toutes les cases sont choisies.


\centerline{\includegraphics{viewgen}}

\begin{verbatim}
<image>
* Section 1 __________ X
 - question 1.1 _____ X
 - question 1.2 _____ o

* Section 2 __________ o
 - question 2.1 _____ X
</image>
\end{verbatim}

L'utilisateur peut dessélectionner les cases associées aux questions
qui ne l'intéressent pas ou diréctement décider qu'il n'est pas intérressé par
toutes les questions d'une section et donc décocher la case
correspondant à la section.


La deuxième façon de définir une vue est intégrée à la consultations
des statistiques associées aux questions. Après avoir affiché la page des
statistiques pour les questions actuellement choisies, l'utilisateur
peut diminuer l'ensemble des questions (toujours à l'aide de cases à
cocher) et réafficher la page des statistiques. Càd l'affichage des
statistiques et la définition de la vue sont fait dans la même page html.

\centerline{\includegraphics{statsnviews}}


\begin{verbatim}
<image>
 ___________________________
 * titre de la question _X_
 ----------------------------
 stat1 : stat2 : stat3 : ...
 ............................
 ____________________________
</image>
\end{verbatim}


\subsubsection{Implémentation des vues}

Une vue est un objet perl, défini dans le module View.pm. Un objet vue
est capable d'initialiser les attributs qui choisissent les questions
importantes, depuis les arguments passés au script par la méthode
POST. Une fois ses attributs intitialisés, l'objet est capable
d'affirmer quelles sections et questions font partie de la vue (à
travers les méthodes contains\_question() et contains\_section()).

Donc désormais, avant de déléguer certainns actions à une de ses
sections, le formulaire vérifie que la section fait partie de la vue
que l'utilisateur a créée, en invoquant la méthode contains\_section()
de la vue. De même pour les sections, avant de déléguer des actions à
une question, la section vérifie que la question appartient à la vue.


(Est-ce que une partie du code d'initialisation de la vue est
convenable ici?)


(Est-ce que une partie du code montrant l'appèle des méthodes serve(),
handle\_submission(), etc des sections par le formulaire et des questions
par les sections est convenable ici)


\subsection{Fiche par Fiche}

La consultation fiche-par-fiche des réponses aux
questionnaire nous permet de voir comment un utilisateur (un étudiant)
a rempli la totalité du questionnaire. Il s'agit d'afficher le
questionnaire, tel qu'il était rempli par un utilisateur/étudiant.

La visite des réponses fiche par fiche est conçue afint d'exploiter
les fonctionnalitées offertes par les filtres et les vues: càd
l'ensemble des fiches sera composé seulement des réponses qui
satisfont au critères définis dans le filtre et chaque fiche
contiendra seulement les réponses aux questions choisies par la vue.

\subsubsection{Comment consulter les réponses}

L'examen du vote fiche par fiche est implémenté comme une nouvelle
action effectué par le formulaire. Donc il suffit d'invoquer le script
avec comme argument CGI action=fpf (meilleures propositions?). Bien
evidemment on peut avoir déja définit un filtre et/ou une vue si
besoin est.



\subsection{Nouvelles statistiques}
On a rajouté un nouveau type de statistiques à la batterie de
statistiques que FOGE proposait déjà - les stats croiseés
(StatsCrossed.pm). Ce type de statistiques est conçu pour mettre à
l'évidence les interdépendences (ou montrer qu'il n'y en a pas) des
réponses à une question en fonction des réponses à une autre question.

\subsubsection{Interpétations de l'information fournie par les StatsCrossed}

\subsubsection{Implémentation (Dépendance du module GD)}


\subsection{Choix dynamique des statistiques}

Il s'agit de donner à l'utilisateur la possibilité de choisir et
reconfigurer les statistiques affichées lors de leur
consultation. Cela nous permet de choisir les statistiques en fonction de la
répartition des réponses. Des fois un camabert dit plus qu'un
histogramme.

\subsubsection{Implémentation}



\subsection{La sécurité de FOGE}

FOGE est créé en raison d'être utilisé à travers des réseaux TCP/IP,
internet en général, et comme toute application exposée à manipulation
d'une publique importante, il doit être bien protégé, c-à-d ne pas
laisser la possibilité à une personne n'ayant pas les droits
nécessaires de corrompre les données et l'application elle-même.

Avant, les modules de FOGE assuraient une distinction basique des
types d'utilisateurs. Les vérifications d'identité se faisaient dans
le module Form qui en général avait pour but de construire le
formulaire et de traiter les différents types d'actions que le
questionnaire proposait. Bref, le processus d'identification n'étaient
que quelques petites fonctions dans le module Form qui vérifiaient que
l'adresse IP appartenait à un certain groupe autorisé. Ces fonctions
ne prenaient pas en compte le type de l'action demandée, elles
retournaient ou "mourraient"...

L'extension dans cet aspect de FOGE consiste en un nouveau module,
nommé SecurityAgent, ayant pour but d'étendre les possibilités de
définition des droits d'accès et de s'occuper des permissions des
usagers pendant les trois différentes étapes de la durée de vie d'un
questionnaire.

L'organisation des droits d'accès est réalisée d'une manière un peu
semblable à celle d'unix, c-à-d une fois connecté un utilisateur est
authentifié soit comme un utilisateur connu, soit comme faisant partie
d'une ou plusieurs groupes, chacun avec des droits spécifiques. Ainsi
le créateur du questionnaire peut spécifier les droits d'accès pour
chaque adresse IP et/ou chaque utilisateur authentifié par un login et
mot de passe, ces derniers obtenus à l'aide du protocole https, ou
simplement par une clé de vote, qui assurera l'anonymat du client et
ses réponses uniques (c-à-d qu'il n'a pas répondu qu'une seule fois).

En général il existent trois types d'usagers : - personne(s) avec des
droits d'administration (tous les droits) - personnes qui posent les
questions; eux ayant la possibilité de consulter certaines ou toutes
les statistiques avant la date limite des soumissions.  - personnes
dont on veut l'opinion. (il se peut que la même personne possède 2
différentes identités pour le formulaire - par exemple dans le cas
d'un formulaire ayant pour but de prévoir les résultats des élections,
le créateur du formulaire voudrait voter lui-aussi..)

La durée de vie d'un questionnaire étant limitée en général, on
distingue trois étapes de l'existence d'un questionnaire :

Étape 1 : Le questionnaire est mis au point, mais il n'est pas encore
autorisé à son audience à soumettre des réponses. Seules certaines
personnes ont le droit de consulter et éventuellement d'apporter des
modifications au formulaire.  Ex. : Un professeur pourrait vouloir
ajouter une question portant sur l'examen final au formulaire
d'évaluation de la maîtrise, mais lors de la création du formulaire
l'examen n'est pas encore prêt... Les modifications online ne sont pas
(encore) implémentés.  Étape 2 : Le questionnaire est disponible aux
soumissions. Pendant ce temps les différents utilisateurs pourront
voir les réponses, les statistiques simples, les statistiques avancées
ou ne rien voir, dépendant de leurs droits d'accès.  Étape 3 : Les
soumissions finies, le formulaire est disponible aux analyses, mais
encore pas tous ont le droit de voir les réponses à toutes les
questions.

La raison la plus importante d'apporter les modifications en créant ce
module n'est pas la besoin d'avoir un système avancé d'identification,
mais la complexité de la manière de choisir quel utilisateur peut voir
quoi et dans quelle période. Les droits d'un utilisateur peuvent
changer lors des trois étapes de l'existence d'un questionnaire donné,
tandis que les droits d'un autre utilisateur du même type (voir types
plus haut) peuvent rester les mêmes ou changer différemment. Et même
si cela peut paraître rarement nécessaire, il y a des cas où une telle
flexibilité aidera à favoriser des questions dont l'on ne voudrait pas
exposer les réponses qu'à un certain groupe d'utilisateurs seulement.

Ayant séparé de cette manière le processus d'évaluation des droits
d'accès de la construction du formulaire rend la configuration des
droits facilement extensible et mieux paramétrable.



\subsubsection{Comment définir les droits d'accès?}

Les droits d'accès sont définis dans le script de génération du
questionnaire lui-même, de manière qu'ils sont figés dedans pour toute
la vie du questionnaire. Ils sont structurés sous forme de hachages et
tableaux imbriqués.  En général les droits se définissent en créant
une instance du module SecurityAgent. Cette instance s'initialise avec
les droits spécifiés comme arguments. Son constructeur la remplit avec
le reste des données nécessaires pour calculer quelles sont les
actions permises pour un utilisateur donné à un instant donné.  Il y
trois catégories de utilisateurs : les super-utilisateurs, les
utilisateurs individuels, et les groupes. Les utilisateurs et les
super-utilisateurs sont authentifiés généralement par https. Les
groupes sont surtout des masques IP, mais rien n'empêche des
utilisateurs reconnus pas https d'être associés à un groupe. Chaque
catégorie est définie à l'aide d'un tableau. Les droits eux-mêmes sont
définis dans deux structures associatives (hachages), en faisant
correspondre à tout utilisateur et tout groupe déjà définis un tableau
composé de trois sous tableaux, un pour chaque
période définie. Les tableaux imbriqués contiennent les droits
explicitement décrits par des combinaisons des mots clés : all, none,
submit, simple\_stats, all\_stats etc.  Les dates de début et fin des
soumissions sont aussi données en arguments.

Voici un exemple d'un appel du constructeur de SecurityAgent :

\begin{verbatim}
my $securisation = CGI::FOGE2::SecurityAgent->new 
    (
# utilisateurs privilégiés :
     superusers   => ("root","admin"),
# autres utilisateurs :
     users        => (addr\_ip1 => "user1", "user2" => "user2"),
# définition des droits d'accès des utilisateurs :
     user_rights  => (
	 "user1"  => (("none"),                          # étape 1
                      ("submit","simple_stats"),         # étape 2
                      ("all_stats")                      # étape 3
                      ),
          "user2"   => (("none"),                 # étape1
                        ("all_stats"),            # étape 2
                        ("all_stats")             # étape 3
                       )
	             ),
# groupes :
     groups        => ("question_askers","replyers","gests", "127.0.0.1"),
# définition des droits d'accès des groupes :
     group_rights  => (
	"question_askers" => (("all"),        # étape 1
                              ("all_stats"),  # étape 2
                              ("all_stats")   # étape 3
                             ),
	"replyers"        => (("none"),
                              ("submit","simple_stats"),
                              ("simple_stats")
                              ),
        "gests"           => (("none"), ("none"), ("simple_stats")),
        "127.0.0.1"       => (("all"),("all"),("all"))
                     ),
     submit_date0 => time(),
     submit_date1 => time()+1000,
);

\end{verbatim}

L'authentification des utilisateurs se fait soit en analysant
seulement leurs adresses IP, soit en leur demandant de fournir un nom
de login et mot de passe, ceci fait automatiquement par le serveur
Apache, il suffit de lui procurer le fichier .htaccess contenant la
directive « require valid-user » dans le répertoire du script
générateur.


Pendant sa création, l'instance de SecurityAgent analysera le
'QUERY\_STRING' et effectuera un contrôle , qui ne permettra aux
utilisateurs d'executer que les actions qui leur sont permises.
(Cela fixe le problème avec 'action=makesql')





\section{Exemple de session}
\begin{itemize}
  \item Se connecter
  \item Choix du filtre
  \item Choix de la vue
  \item Visualiser les statistiques
  \item Revisualiser les statistiques en diminuant l'ensemble des
  questions affichées, et en choisissant des statistiques, autres que
  celle choisi par le concepteur
\end{itemize}

\section{Conclusion}

D'un coté le travail réalisé nous a confronté à différentes problèmes
qu'on a su résoudre.  Le language de programmaton par
exemple.  Les connaissances en Perl de IB et GT se limitaient au cour
de Programmation Reticulaire de la Licence d'Informatique, alors que
OP débutait en Perl (Une des raisons de choisir ce sujet de TER était
donc d'approfondir nos connaissence en perl, BD et programmation
CGI). De plus, Perl étant un language qui n'est pas adapté "à la
lecture" (même avec le souci d'écrire un code lisible et bien
commenté), la compréhension du fonctionnement de Foge a demandé un
effort considérable.

D'autre part le travail sur le TER repésente pour nous une expérience
profitable.  On a acquis une bonne maitruse de Perl, Postgres et
Apache.  On a su réspecter les contraites liés à la résolution d'un
problème concret (contrainte temporelle, de lanquage, d'integration du
code). C'était aussi l'occasion de travailler en equipe - discuter,
combiner de différentes solutions, trouver le meilleure. Et
finalement on a eu la possibilité da travailler sur un "vrai"
logiciel, de comprendre, d'améliorer, et cela sous la direction de son
concepteur!

***********************

On a même été confrontés à un bug dans apache
"http://nagoya.apache.org/bugzilla/show\_bug.cgi?id=22030", qui se
manifeste lorsque le script produit beaucoup de messages de controle
vers le fichier de log du serveur.

\end{document}
